package com.ybg.block.core.fabric;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ybg.block.core.dbapi.entity.FabricBlock;
import com.ybg.block.core.fabric.datamapper.FabricChannelDataMapper;
import com.ybg.block.core.dbapi.entity.FabricChannel;
import com.ybg.block.core.dbapi.entity.FabricPeer;
import com.ybg.block.core.dbapi.service.FabricBlockService;
import com.ybg.block.core.dbapi.service.FabricChaincodeService;
import com.ybg.block.core.dbapi.service.FabricChannelService;
import com.ybg.block.core.dbapi.service.FabricPeerService;
import com.ybg.share.core.fabric.FabricChannelRemoteApi;
import com.ybg.share.core.fabric.dto.FabricChannelEditDTO;
import com.ybg.share.core.fabric.dto.FabricChannelQueryDTO;
import com.ybg.share.core.fabric.vo.FabricChannelVO;
import com.ybg.framework.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service(version = "${dubbo.provider.version}", timeout = 120000, cache = "false")
public class FabricChannelRemoteApiImpl implements FabricChannelRemoteApi {
    @Autowired
    private FabricChannelService fabricChannelService;
    @Autowired
    private FabricBlockService fabricBlockService;
    @Autowired
    private FabricChaincodeService fabricChaincodeService;
    @Autowired
    private FabricPeerService fabricPeerService;


    @Override
    public R<?> editFabricChannel(FabricChannelEditDTO dto) {
        FabricPeer fabricPeer = null;
        FabricChannel fabricChannel = null;
        if (dto.getId() == null && dto.getPeerId() == null) {
            return R.fail("请选择节点");
        }
        if (StrUtil.isBlank(dto.getName())) {
            return R.fail("请输入通道名称");
        }
        if (dto.getBlockListener() == null) {
            return R.fail("请选择是否监听区块");
        }
        if (dto.getBlockListener() && StrUtil.isBlank(dto.getCallbackLocation())) {
            return R.fail("同步区块监听回调地址不合法");
        }
        if (dto.getId() == null && dto.getPeerId() != null) {
            fabricPeer = fabricPeerService.getById(dto.getPeerId());
            if (fabricPeer == null) {
                return R.fail("节点不存在");
            }
        }
        if (dto.getId() != null) {
            fabricChannel = fabricChannelService.getById(dto.getId());
            if (fabricChannel == null) {
                return R.fail("通道不存在");
            }
            fabricPeer = fabricPeerService.getById(fabricChannel.getPeerId());
        }
        if (fabricChannel == null) {
            fabricChannel = new FabricChannel();
        }
        fabricChannel.setName(dto.getName());
        fabricChannel.setBlockListener(dto.getBlockListener());
        fabricChannel.setCallbackLocation(dto.getCallbackLocation());
        fabricChannel.setPeerId(dto.getPeerId());
        fabricChannel.setCreateTime(LocalDateTime.now());
        fabricChannel.setLeagueId(fabricPeer.getLeagueId());
        fabricChannel.setOrgId(fabricPeer.getOrgId());
        fabricChannel.setPeerName(fabricPeer.getName());
        fabricChannel.setOrgName(fabricPeer.getOrgName());
        fabricChannel.setLeagueName(fabricPeer.getLeagueName());
        // fabricChannel.setChaincodeCount();
        fabricChannelService.saveOrUpdate(fabricChannel);
        return R.success();
    }

    @Override
    public R<?> deleteById(Long id) {
        FabricChannel fabricChannel = fabricChannelService.getById(id);
        if (fabricChannel == null) {
            return R.fail("删除失败数据不存在");
        }
        fabricChannelService.removeById(id);
        //删除有关这个通道的
        Map<String, Object> condition = new LinkedHashMap<>();
        condition.put(FabricBlock.CHANNEL_ID, id);
        fabricBlockService.removeByMap(condition);
        fabricChaincodeService.removeByMap(condition);
        fabricBlockService.removeByMap(condition);
        return R.success();
    }

    @Override
    public R<List<FabricChannelVO>> query(FabricChannelQueryDTO dto) {
        QueryWrapper<FabricChannel> wrapper = new QueryWrapper<>();
        wrapper.eq(dto.getId() == null, FabricChannel.ID, dto.getId());
        wrapper.eq(dto.getLeagueId() != null, FabricChannel.LEAGUE_ID, dto.getLeagueId());
        wrapper.eq(dto.getOrgId() != null, FabricChannel.ORG_ID, dto.getOrgId());
        wrapper.eq(dto.getPeerId() != null, FabricChannel.PEER_ID, dto.getPeerId());
        List<FabricChannel> fabricChannels = fabricChannelService.list(wrapper);
        return R.success(FabricChannelDataMapper.INSTANCE.toVOList(fabricChannels));
    }

    @Override
    public R<FabricChannelVO> getById(Long id) {
        FabricChannel fabricChannel = fabricChannelService.getById(id);
        return R.success(FabricChannelDataMapper.INSTANCE.toVO(fabricChannel));
    }
}
